#include <bits/stdc++.h>
using namespace std;
const int N = 200005; // 定义最大数据范围

// 线段树节点结构
struct node {
  int mx, mi; // mx: 左端点对应的最大右端点，mi: 右端点对应的最小左端点
} seg[N * 4]; // 线段树数组，大小为4*N以确保足够空间

// 显式的pushup函数，用于合并左右子节点更新当前节点
void pushup(int id) {
  seg[id].mx = max(seg[id * 2].mx, seg[id * 2 + 1].mx);
  seg[id].mi = min(seg[id * 2].mi, seg[id * 2 + 1].mi);
}

// 构建线段树
// id: 当前节点编号，l和r: 当前节点表示的区间
void build(int id, int l, int r) {
  seg[id].mx = 0;     // 初始化mx为0
  seg[id].mi = 1e9;   // 初始化mi为一个很大的值(1e9)
  if (l == r)         // 叶子节点处理
    return;
  int mid = l + r >> 1;       // 计算中间点
  build(id * 2, l, mid);      // 递归构建左子树
  build(id * 2 + 1, mid + 1, r); // 递归构建右子树
}

// 更新操作1：更新某个位置的mx值
// id: 当前节点编号，l和r: 当前节点表示的区间，pos: 要更新的位置，x: 新的mx值
void change1(int id, int l, int r, int pos, int x) {
  if (l == r) {       // 到达叶子节点
    seg[id].mx = x;   // 更新mx值
    return;
  }
  int mid = l + r >> 1;       // 计算中间点
  if (pos <= mid)             // 如果要更新的位置在左子树
    change1(id * 2, l, mid, pos, x);
  else                        // 如果要更新的位置在右子树
    change1(id * 2 + 1, mid + 1, r, pos, x);
  pushup(id); // 调用显式的pushup函数，合并左右子树的结果，更新当前节点
}

// 更新操作2：更新某个位置的mi值
// id: 当前节点编号，l和r: 当前节点表示的区间，pos: 要更新的位置，x: 新的mi值
void change2(int id, int l, int r, int pos, int x) {
  if (l == r) {       // 到达叶子节点
    seg[id].mi = x;   // 更新mi值
    return;
  }
  int mid = l + r >> 1;       // 计算中间点
  if (pos <= mid)             // 如果要更新的位置在左子树
    change2(id * 2, l, mid, pos, x);
  else                        // 如果要更新的位置在右子树
    change2(id * 2 + 1, mid + 1, r, pos, x);
  pushup(id); // 调用显式的pushup函数，合并左右子树的结果，更新当前节点
}

// 查询操作：查询区间[ql, qr]中的最大mx和最小mi
// id: 当前节点编号，l和r: 当前节点表示的区间，ql和qr: 查询的区间
node query(int id, int l, int r, int ql, int qr) {
  if (ql <= l && qr >= r)     // 当前区间完全包含在查询区间内
    return seg[id];
  int mid = l + r >> 1;       // 计算中间点
  if (qr <= mid)              // 查询区间完全在左子树
    return query(id * 2, l, mid, ql, qr);
  if (ql > mid)               // 查询区间完全在右子树
    return query(id * 2 + 1, mid + 1, r, ql, qr);
  // 查询区间跨越左右子树，分别查询后合并结果
  node left = query(id * 2, l, mid, ql, qr);
  node right = query(id * 2 + 1, mid + 1, r, ql, qr);
  node res;
  res.mx = max(left.mx, right.mx);
  res.mi = min(left.mi, right.mi);
  return res;
}

// 主函数
int main() {
  int n, q;           // n: 数据范围，q: 查询次数
  cin >> n >> q;      // 读取输入
  build(1, 1, n);     // 构建线段树，根节点编号为1，区间为[1, n]
  while (q--) {       // 处理每个查询
    int a, b;         // 读取要插入的区间[a, b]
    cin >> a >> b;
    int ok = 1;       // 标记是否可以插入该区间，初始为可以
    
    // 检查区间[a, b]内部是否存在冲突
    // 只有当a+1 <= b-1时，中间才有点需要检查
    if (a + 1 <= b - 1) {
      // 查询区间[a+1, b-1]中的最大mx和最小mi
      auto ans = query(1, 1, n, a + 1, b - 1);
      // 冲突条件：
      // 1. 中间任意点的mx > b：表示存在一个区间左端点在中间，右端点超过了b
      // 2. 中间任意点的mi < a：表示存在一个区间右端点在中间，左端点小于a
      if (ans.mx > b || ans.mi < a)
        ok = 0;  // 存在冲突，标记为不可插入
    }
    
    if (ok == 1) {     // 如果可以插入
      cout << "Yes" << endl;
      // 更新：a作为左端点，其右端点为b
      change1(1, 1, n, a, b);
      // 更新：b作为右端点，其左端点为a
      change2(1, 1, n, b, a);
    } else {          // 如果不可插入
      cout << "No" << endl;
    }
  }
  return 0;
}